package com.example.remote;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.SocketException;
import java.net.UnknownHostException;

public class Client1 {
    private static final int CLIENT_PORT = 54321;
    private static final String SERVER_IP = "192.168.0.102";
    private static final int SERVER_PORT = 12345;
    private static DatagramSocket socket;

    public static void main(String[] args) {
        try {
            socket = new DatagramSocket(CLIENT_PORT);
            // 注册到服务器
            registerToServer("CLIENT1");

            // 获取要连接的客户端地址（这里假设要连接CLIENT2）
            InetSocketAddress targetAddress = getTargetClientAddress("CLIENT2");

            // UDP打洞
            sendInitialPackets(targetAddress);

            // 开始直连通信
            startDirectCommunication(targetAddress);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private static void registerToServer(String clientId) throws Exception {
        String registerMessage = "REGISTER:" + clientId;
        byte[] data = registerMessage.getBytes();
        DatagramPacket packet = new DatagramPacket(data, data.length, InetAddress.getByName(SERVER_IP), SERVER_PORT);
        socket.send(packet);
    }

    private static InetSocketAddress getTargetClientAddress(String targetClientId) throws Exception {
        String getClientMessage = "GET_CLIENT:" + targetClientId;
        byte[] data = getClientMessage.getBytes();
        DatagramPacket packet = new DatagramPacket(data, data.length, InetAddress.getByName(SERVER_IP), SERVER_PORT);
        socket.send(packet);
        byte[] buffer = new byte[1024];
        DatagramPacket responsePacket = new DatagramPacket(buffer, buffer.length);
        socket.receive(responsePacket);
        String hostPort = new String(responsePacket.getData(), 0, responsePacket.getLength(), "UTF-8");
        String[] split = hostPort.split(":");

        String host = split[0];
        String port = split[1];
        InetAddress targetInetAddress = InetAddress.getByName(host);
        // 从服务器存储中获取端口号（假设方式，这里简化处理）
        int targetPort = Integer.valueOf(port);
        return new InetSocketAddress(targetInetAddress, targetPort);
    }

    private static void sendInitialPackets(InetSocketAddress targetAddress) throws IOException {
        // 发送初始数据包进行UDP打洞
        DatagramSocket tempSocket = new DatagramSocket();
        String link = "I am client1, your address is: " + targetAddress.getAddress().getHostAddress() + ":" + targetAddress.getPort();
        byte[] data = link.getBytes();
        DatagramPacket packet = new DatagramPacket(data, data.length, targetAddress.getAddress(), targetAddress.getPort());
        tempSocket.send(packet);
        tempSocket.close();
    }

    private static void startDirectCommunication(InetSocketAddress targetAddress) throws Exception {
        byte[] buffer = new byte[1024];
        while (true) {
            DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
            socket.receive(packet);
            System.out.println("Client1 Received: " + new String(packet.getData(), 0, packet.getLength()));
            byte[] sendData = "Response from Client1".getBytes();
            DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, targetAddress.getAddress(), packet.getPort());
            socket.send(sendPacket);
        }
    }
}

